/*
 *  +----------------------------------------------------------------------
 *  | sophon [ A FAST GAME FRAMEWORK ]
 *  +----------------------------------------------------------------------
 *  | Copyright (c) 2023-2029 All rights reserved.
 *  +----------------------------------------------------------------------
 *  | Licensed ( http:www.apache.org/licenses/LICENSE-2.0 )
 *  +----------------------------------------------------------------------
 *  | Author: jqiris <1920624985@qq.com>
 *  +----------------------------------------------------------------------
 */

use std::sync::atomic::{AtomicI64, Ordering};

use chrono::Local;

pub struct Counter {
    count: AtomicI64,
    interval: i64,
    sync_time: AtomicI64,
}

impl Counter {
    pub fn new(init_count: i64, interval: i64) -> Self {
        let count = AtomicI64::new(init_count);
        let sync_time = AtomicI64::new(Local::now().timestamp());
        Counter { count, sync_time, interval }
    }

    fn sync(&self, value: i64) -> bool {
        self.count.store(value, Ordering::SeqCst);
        let (now_time, sync_time) = (Local::now().timestamp(), self.sync_time.load(Ordering::SeqCst));
        let diff_time = now_time - sync_time;
        // println!("now_time:{},sync_time:{},diff_time:{}", now_time, sync_time, diff_time);
        if diff_time >= self.interval {
            //同步数据
            self.sync_time.store(Local::now().timestamp(), Ordering::SeqCst);
            // println!("return load:{}", value);
            return true;
        }
        false
    }
    pub fn inc(&self, num: i64) -> (i64, bool) {
        let mut value = self.count.load(Ordering::SeqCst);
        value += num;
        // println!("inc num:{},value:{}", num, value);
        (value, self.sync(value))
    }

    pub fn dec(&self, num: i64) -> (i64, bool) {
        let mut value = self.count.load(Ordering::SeqCst);
        value -= num;
        // println!("dec num:{},value:{}", num, value);
        (value, self.sync(value))
    }
}